use std::{
    collections::HashMap,
    sync::{Arc, Mutex},
};

use bytes::Bytes;
use mini_redis::{Command, Connection, Frame};
use tokio::net::{TcpListener, TcpStream};
type Db = Arc<Mutex<HashMap<String, Bytes>>>;

#[tokio::main]
async fn main() {
    
    let listener = TcpListener::bind("127.0.0.1:6379").await.unwrap();
    println!("The server is listening on port 6379");
    let db: Db = Arc::new(Mutex::new(HashMap::new()));

    loop {
        let (socket, _) = listener.accept().await.unwrap();
        let db = db.clone();
        // 为每一条连接都生成一个新的任务，
        // `socket` 的所有权将被移动到新的任务中，并在那里进行处理
        tokio::spawn(async move {
            process(socket, db).await;
        });
    }
}

async fn process(socket: TcpStream, db: Db) {
    let mut connection = Connection::new(socket);
    while let Some(frame) = connection.read_frame().await.unwrap() {
        let response = {
            // let db = db.lock().unwrap();
            match Command::from_frame(frame).unwrap() {
                Command::Set(cmd) => {
                    db.lock().unwrap().insert(cmd.key().to_string(), cmd.value().clone());
                    Frame::Simple(String::from("OK"))
                }
                Command::Get(cmd) => {
                    if let Some(value) = db.lock().unwrap().get(cmd.key()) {
                        Frame::Bulk(value.clone().into())
                    } else {
                        Frame::Null
                    }
                }
                cmd => panic!("未实现的方法: {cmd:?}"),
            }
        };
        connection.write_frame(&response).await.unwrap();
    }
}
